package com.glodon.paas.job.monitor.profile;

import java.util.UUID;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.glodon.paas.job.model.MonitorEvent;

@Aspect
@Component
@SuppressWarnings("unused")
public class ProfileHandler {
    private static final Logger logger = LoggerFactory.getLogger("monitor");

    @Pointcut("@annotation(com.glodon.paas.job.monitor.profile.Profile)")
    private void profileMethod() {
    }

    @Around("profileMethod()")
    private Object profileHandler(final ProceedingJoinPoint joinPoint) throws Throwable {
        UUID uuid = UUID.randomUUID();
        final String id = uuid.toString();
        if (logger.isInfoEnabled()) {
            logger.info("start invoke method", new MonitorEvent() {
                {
                    setType("invoke");
                    setTraceId(id);
                    setTraceIndex(true);
                    addValue("class", joinPoint.getClass());
                    addValue("method", joinPoint.getSignature());
                }
            });
        }
        try {
            final Object result = joinPoint.proceed();
            if (logger.isInfoEnabled()) {
                logger.info("end invoke method", new MonitorEvent() {
                    {
                        setType("invoke");
                        setTraceId(id);
                        setTraceIndex(true);
                        addValue("class", joinPoint.getClass());
                        addValue("method", joinPoint.getSignature());
                        addValue("result value", result);
                    }
                });
            }
            return result;
        } catch (final Throwable e) {
            if (logger.isInfoEnabled()) {
                logger.info("end invoke method", new MonitorEvent() {
                    {
                        setType("invoke");
                        setTraceId(id);
                        setTraceIndex(true);
                        addValue("class", joinPoint.getClass());
                        addValue("method", joinPoint.getSignature());
                        addValue("error", e.getMessage());
                    }
                });
            }
            throw e;
        }
    }
}
